package com.sky.rabc.utils;


import org.bouncycastle.util.encoders.Base64;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

/**
 * @author 许照
 * @className AesCommon
 * @description AES加解密
 * @date 2024/5/28
 */
public class AesCommon {
    //加密方式
    private static final String KEY_ALGORITHM = "AES";
    //数据填充方式
    public static final String AES_CBC_PKCS7 = "AES/CBC/PKCS7Padding";
    public static final String AES_CBC_PKCS5 = "AES/CBC/PKCS5Padding";

    /*  static {
          Security.addProvider(new BouncyCastleProvider());
      }
  */
    public static Cipher cipher(String paddingMode) throws NoSuchPaddingException, NoSuchAlgorithmException {
        return Cipher.getInstance(paddingMode);
    }

    /**
     * AES加密
     *
     * @param content     明文
     * @param encryptKey  密钥 16bytes 24bytes 32bytes
     * @param iv          偏移量  密钥 16bytes
     * @param paddingMode 数据填充模式 AesCommon.AES_CBC_PKCS5
     * @return byte[] 字节数组
     */
    public static byte[] encrypt(String content, String encryptKey, String iv, String paddingMode) throws Exception {
        Cipher cipher = cipher(paddingMode);
        SecretKeySpec keySpec = new SecretKeySpec(encryptKey.getBytes(), KEY_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, generateIV(iv.getBytes()));
        return cipher.doFinal(content.getBytes());
    }

    /**
     * AES加密
     *
     * @param content     明文
     * @param encryptKey  密钥 16bytes 24bytes 32bytes
     * @param iv          偏移量  密钥 16bytes
     * @param paddingMode 数据填充模式 AesCommon.AES_CBC_PKCS5
     * @return base64后的字符串
     */
    public static String encryptToStr(String content, String encryptKey, String iv, String paddingMode) throws Exception {
        byte[] bytes = encrypt(content, encryptKey, iv, paddingMode);
        return Base64.toBase64String(bytes);
    }

    /**
     * AES解密
     *
     * @param contentBytes    密文字节数组
     * @param encryptKeyBytes 密钥字节数组
     * @param ivBytes         偏移量字节数组
     * @param paddingMode     数据填充模式 AesCommon.AES_CBC_PKCS5
     * @return byte[] 原文字节数组
     */
    public static byte[] decrypt(byte[] contentBytes, byte[] encryptKeyBytes, byte[] ivBytes, String paddingMode) throws Exception {
        Cipher cipher = cipher(paddingMode);
        Key sKeySpec = new SecretKeySpec(encryptKeyBytes, KEY_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivBytes));
        return cipher.doFinal(contentBytes);
    }

    /**
     * AES解密,密文必须是base64后的
     *
     * @param content     密文
     * @param encryptKey  密钥
     * @param iv          偏移量
     * @param paddingMode 数据填充模式 AesCommon.AES_CBC_PKCS5
     * @return String 原文
     */
    public static String decryptToStr(String content, String encryptKey, String iv, String paddingMode) throws Exception {
        //先将密文进行base64解码
        byte[] decodeBytes = Base64.decode(content);
        byte[] bytes = decrypt(decodeBytes, encryptKey.getBytes(), iv.getBytes(), paddingMode);
        return new String(bytes);
    }

    // 生成iv
    public static AlgorithmParameters generateIV(byte[] ivBytes) throws Exception {
        AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_ALGORITHM);
        params.init(new IvParameterSpec(ivBytes));
        return params;
    }


}
